package org.ph.share._02_CreateThread;


import java.util.concurrent.*;
import java.util.stream.IntStream;

public class _01_CreateThread_Run {
    public void newTask1() {
        Thread thread = new Thread();
        thread.start();
    }

    public void newTask2() {
        Runnable runnable = () -> {
            System.out.println("runnable-创建" + Thread.currentThread().getName());
        };
        new Thread(runnable).start();
    }

    /**
     * 使用FutureTask创建线程
     */
    public void newTask3() throws ExecutionException, InterruptedException {
        //FutureTask的父类是Runnable
        FutureTask<String> target = new FutureTask<>(
                () -> {
                    String s = "FutureTask-创建" + Thread.currentThread().getName();
                    System.out.println(s);
                    return s;
                });
        Thread thread = new Thread(target);
        thread.start();

        //主进程可以获取线程的运算结果，但是不利于控制服务器中的线程资源
        System.out.println(target.get());
    }

    /**
     * 线程池创建线程
     */
    public static void newTask4() {
        //在实际开发使用java的Executors来创建线程时会有OOM的风险
        //该方法的任务执行前保存的队列是无界的(或者默认是Integer.MAX_VALUE)
        //任务数太多而导致内存溢出
        //FixedThreadPool和SingleThreadPool允许等待的请求队列是Integer.MAX_VALUE 可能导致内存溢出。 而CachedThreadPool和shceduledThreadPool允许创建的线程数量是Integer.MAX_VALUE 同样会出现内存溢出。
        ExecutorService service = Executors.newSingleThreadExecutor();
        service.execute(() -> {
            System.out.println("线程池-创建" + Thread.currentThread().getName());
        });

        service.shutdown();

        //创建线程的正确姿势
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3, 10, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<>(5),new ThreadPoolExecutor.DiscardOldestPolicy());
        IntStream.rangeClosed(1, 100).forEach((i) -> {
            poolExecutor.execute(() -> {
                System.out.println("有边界队列线程池-创建 index::" + i + Thread.currentThread().getName());
            });
        });
        poolExecutor.shutdown();
    }


    public static void main(String[] args) {
        //newTask4();
        Thread thread = new Thread() {
            @Override
            public void run() {
                System.out.println("我是子线程");
            }
        };
        thread.start();
        System.out.println("main 结束");
    }
}
